import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;


public class DiKeSong extends Method{

	private float r0 = 0;		// 从表中查处的r0 值
	private final Hashtable<String, Float> R0 = new Hashtable<String, Float>();	// 表

	public DiKeSong(ArrayList<Float> data, int format) {
		this(data, 0.05f, format);
	}
	
	public DiKeSong(ArrayList<Float> data, float alpha, int format) {
		super(data, format);
		this.name = "狄克松准则";
		initR0();
		r0 = getR0(data.size(),alpha);
	}

	@Override
	protected boolean hasGrossError(){
		Collections.sort(data);
		int n = data.size();
		float r = 0;
		if(n<8) {
			r = (data.get(0) - data.get(1)) / (data.get(0)-data.get(n-1));
		}else if(n<11){
			r = (data.get(0) - data.get(1)) / (data.get(0)-data.get(n-2));
		}else if(n<14){
			r = (data.get(0) - data.get(2)) / (data.get(0)-data.get(n-2));
		}else{
			r = (data.get(0) - data.get(2)) / (data.get(0)-data.get(n-3));
		}
		if(r>r0){
			blackList.add(data.get(0));
			return true;
		}
		if(n<8) {
			r = (data.get(n-1) - data.get(n-2)) / (data.get(n-1)-data.get(0));
		}else if(n<11){
			r = (data.get(n-1) - data.get(n-2)) / (data.get(n-1)-data.get(1));
		}else if(n<14){
			r = (data.get(n-1) - data.get(n-3)) / (data.get(n-1)-data.get(1));
		}else{
			r = (data.get(n-1) - data.get(n-3)) / (data.get(n-1)-data.get(2));
		}
		if(r>r0){
			blackList.add(data.get(n-1));
			return true;
		}
		return false;
	}
	
	/**
	 *	查表已取得r0 值
	 */
	private float getR0(int n, float alpha){
		if(n<3) n=3;
		if(n>25) n=25;
		return R0.get(n+"&"+alpha);
	}
	
	/**
	 *	初始化表
	 */
	private void initR0(){
		R0.put("3&0.01", 0.988f);		R0.put("3&0.05", 0.341f);
		R0.put("4&0.01", 0.889f);		R0.put("4&0.05", 0.765f);
		R0.put("5&0.01", 0.780f);		R0.put("5&0.05", 0.642f);
		R0.put("6&0.01", 0.698f);		R0.put("6&0.05", 0.560f);
		R0.put("7&0.01", 0.637f);		R0.put("7&0.05", 0.507f);
		R0.put("8&0.01", 0.683f);		R0.put("8&0.05", 0.554f);
		R0.put("9&0.01", 0.635f);		R0.put("9&0.05", 0.512f);
		R0.put("10&0.01", 0.597f);		R0.put("10&0.05", 0.477f);
		R0.put("11&0.01", 0.679f);		R0.put("11&0.05", 0.576f);
		R0.put("12&0.01", 0.642f);		R0.put("12&0.05", 0.546f);
		R0.put("13&0.01", 0.615f);		R0.put("13&0.05", 0.521f);
		R0.put("14&0.01", 0.641f);		R0.put("14&0.05", 0.546f);
		R0.put("15&0.01", 0.616f);		R0.put("15&0.05", 0.525f);
		R0.put("16&0.01", 0.595f);		R0.put("16&0.05", 0.507f);
		R0.put("17&0.01", 0.577f);		R0.put("17&0.05", 0.490f);
		R0.put("18&0.01", 0.561f);		R0.put("18&0.05", 0.475f);
		R0.put("19&0.01", 0.547f);		R0.put("19&0.05", 0.462f);
		R0.put("20&0.01", 0.535f);		R0.put("20&0.05", 0.450f);
		R0.put("21&0.01", 0.524f);		R0.put("21&0.05", 0.440f);
		R0.put("22&0.01", 0.514f);		R0.put("22&0.05", 0.430f);
		R0.put("23&0.01", 0.505f);		R0.put("23&0.05", 0.421f);
		R0.put("24&0.01", 0.497f);		R0.put("24&0.05", 0.413f);
		R0.put("25&0.01", 0.489f);		R0.put("25&0.05", 0.406f);
	}
}